/*******************************************************************************
* intc driver
* kerndev@foxmail.com
*******************************************************************************/
#include <string.h>
#include <stdint.h>
#include "intc.h"

typedef struct
{
	uint32_t SRCPND;
	uint32_t INTMOD;
	uint32_t INTMSK;
	uint32_t PRIORITY;
	uint32_t INTPND;
	uint32_t INTOFFSET;
	uint32_t SUBSRCPND;
	uint32_t INTSUBMSK;
}INTC_DEF;

#define INTC ((volatile INTC_DEF*)0x4A000000)

static uint32_t m_vector[IRQ_MAX];

void intc_init(void)
{
	INTC->INTMSK = ~0;
	INTC->INTPND = ~0;
	INTC->SRCPND = ~0;
	memset(m_vector, 0, sizeof(m_vector));
}

void intc_set_handler(irq_type_t irq, void (*isr)(void))
{
	m_vector[irq] = (uint32_t)isr;
}

void intc_set_priority(irq_type_t irq, int prio)
{

}

void intc_enable_irq(irq_type_t irq)
{
	INTC->INTMSK &= ~(1 << irq);
}

void intc_disable_irq(irq_type_t irq)
{
	INTC->INTMSK |= (1 << irq);
}

void intc_handler(void)
{
	typedef void (*func_t)(void);
	uint32_t ofs = INTC->INTOFFSET;
	func_t   isr = (func_t)m_vector[ofs];
	INTC->SRCPND = 1 << ofs;
	INTC->INTPND = 1 << ofs;
	if((ofs < IRQ_MAX) && (isr != NULL))
	{
		isr();
	}
}
